/**
 * Copyright 2019 asiainfo Inc.
 **/
package com.myz.rabbitmqspring.spring.listen;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.concurrent.TimeUnit;

/**
 * 实现消息返回机制
 *
 * @author maoyz0621 on 19-1-17
 * @version: v1.0
 */
public class ReturnCallbackListener implements RabbitTemplate.ReturnCallback {

    private static final Logger log = LoggerFactory.getLogger(ReturnCallbackListener.class);

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 实现此方法在basicpublish失败时回调
     * 相当于 ReturnListener的功能。
     * 在发布消息时设置mandatory等于true，
     * 监听消息是否有相匹配的队列，没有时ReturnCallback将执行returnedMessage方法，消息将返给发送者
     * <p>
     * 使用return-callback时必须设置mandatory为true，或者在配置中设置mandatory-expression的值为true，
     * 可针对每次请求的消息去确定'mandatory'的boolean值，
     * 只能在提供'return -callback'时使用，与mandatory互斥
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        try {
            TimeUnit.MICROSECONDS.sleep(200);
            log.error("MsgSendReturnCallback [消息从交换机到队列失败] " + replyText
                    + ";错误代码（replyCode）：" + replyCode
                    + ";消息对象：" + new String(message.getBody(), "UTF-8")
                    + "exchange:" + exchange
                    + "routingKey:" + routingKey);
            // 发送信息
            rabbitTemplate.send(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
